package org.jeecg.modules.demo.ipds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.ipds.entity.*;
import org.jeecg.modules.demo.ipds.mapper.*;
import org.jeecg.modules.demo.ipds.service.IIpTreeService;
import org.jeecg.modules.demo.ipds.service.ITreeByteListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 协议章节树
 * @Author: jeecg-boot
 * @Date:   2024-01-29
 * @Version: V1.0
 */
@Service
public class IpTreeServiceImpl extends ServiceImpl<IpTreeMapper, IpTree> implements IIpTreeService {


    @Autowired
    private TreeByteListMapper treeByteListMapper;
    @Autowired
    private ITreeByteListService treeByteListService;

    @Autowired
    private TreeByteListMapper2 treeByteListMapper2;

    @Autowired
    private BitListMapper bitListMapper;

    @Autowired
    private ByteFrameZuMapper byteFrameZuMapper;

	@Override
	public void addIpTree(IpTree ipTree) {
	   //新增时设置hasChild为0
	    ipTree.setHasChild(IIpTreeService.NOCHILD);
		if(oConvertUtils.isEmpty(ipTree.getPid())){
			ipTree.setPid(IIpTreeService.ROOT_PID_VALUE);
		}else{
			//如果当前节点父ID不为空 则设置父节点的hasChildren 为1
			IpTree parent = baseMapper.selectById(ipTree.getPid());
			if(parent!=null && !"1".equals(parent.getHasChild())){
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}
		}
		baseMapper.insert(ipTree);
	}
	
	@Override
    @Transactional(rollbackFor = Exception.class)
	public void updateIpTree(IpTree ipTree) {
		IpTree entity = this.getById(ipTree.getId());
		if(entity==null) {
			throw new JeecgBootException("未找到对应实体");
		}
		String old_pid = entity.getPid();
		String new_pid = ipTree.getPid();
		if(!old_pid.equals(new_pid)) {
			updateOldParentNode(old_pid);
			if(oConvertUtils.isEmpty(new_pid)){
				ipTree.setPid(IIpTreeService.ROOT_PID_VALUE);
			}
			if(!IIpTreeService.ROOT_PID_VALUE.equals(ipTree.getPid())) {
				baseMapper.updateTreeNodeStatus(ipTree.getPid(), IIpTreeService.HASCHILD);
			}
		}
		baseMapper.updateById(ipTree);

	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteIpTree(String id) throws JeecgBootException {
		//查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if(id.indexOf(",")>0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if(idVal != null){
                    IpTree ipTree = this.getById(idVal);
                    String pidVal = ipTree.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<IpTree> dataList = baseMapper.selectList(new QueryWrapper<IpTree>().eq("pid", pidVal).notIn("id",Arrays.asList(idArr)));
                    boolean flag = (dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal) && !sb.toString().contains(pidVal);
                    if(flag){
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for(String pid : pidArr){
                this.updateOldParentNode(pid);
            }
        }else{
            IpTree ipTree = this.getById(id);
            if(ipTree==null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(ipTree.getPid());
            baseMapper.deleteById(id);
        }
	}
	
	@Override
    public List<IpTree> queryTreeListNoPage(QueryWrapper<IpTree> queryWrapper) {
        List<IpTree> dataList = baseMapper.selectList(queryWrapper);
        List<IpTree> mapList = new ArrayList<>();
        for(IpTree data : dataList){
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if(pidVal != null && !IIpTreeService.NOCHILD.equals(pidVal)){
                IpTree rootVal = this.getTreeRoot(pidVal);
                if(rootVal != null && !mapList.contains(rootVal)){
                    mapList.add(rootVal);
                }
            }else{
                if(!mapList.contains(data)){
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<SelectTreeModel> queryListByCode(String parentCode) {
        String pid = ROOT_PID_VALUE;
        if (oConvertUtils.isNotEmpty(parentCode)) {
            LambdaQueryWrapper<IpTree> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(IpTree::getPid, parentCode);
            List<IpTree> list = baseMapper.selectList(queryWrapper);
            if (list == null || list.size() == 0) {
                throw new JeecgBootException("该编码【" + parentCode + "】不存在，请核实!");
            }
            if (list.size() > 1) {
                throw new JeecgBootException("该编码【" + parentCode + "】存在多个，请核实!");
            }
            pid = list.get(0).getId();
        }
        return baseMapper.queryListByPid(pid, null);
    }

    @Override
    public List<SelectTreeModel> queryListByPid(String pid) {
        if (oConvertUtils.isEmpty(pid)) {
            pid = ROOT_PID_VALUE;
        }
        return baseMapper.queryListByPid(pid, null);
    }

    @Override
    public List<IpTree> queryListByWordId(String wordId) {
        QueryWrapper<IpTree> ipTreeQueryWrapper = new QueryWrapper<>();
        ipTreeQueryWrapper.eq("word_id", wordId);
        List<IpTree> ipTrees = baseMapper.selectList(ipTreeQueryWrapper);


        //组装成父子的树形结构
        //找到所有的一级分类
        List<IpTree> collect = ipTrees.stream().filter(IpTree ->
                IpTree.getPid().equals("0")
        ).map((menu)->{
            if (menu.getType().equals("协议")){
                String tree_id = menu.getId();
                String sectionName = menu.getSectionName();
                QueryWrapper<TreeByteList>  treeByteListQueryWrapper = new QueryWrapper<>();
                //往树里面添加字节
                treeByteListQueryWrapper.eq("ip_tree_id",tree_id);
                treeByteListQueryWrapper.orderByAsc("index_sx");

                List<TreeByteList> treeByteLists = treeByteListMapper.selectList(treeByteListQueryWrapper);
                List<IpTree> byteList = new LinkedList<>();
                for (TreeByteList treeByteList : treeByteLists) {
                    QueryWrapper<ByteFrameZu> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("byte_id",treeByteList.getId());
                    queryWrapper.orderByAsc("index_sx");
                    List<ByteFrameZu> byteFrameZus = byteFrameZuMapper.selectList(queryWrapper);

                    if (!byteFrameZus.isEmpty() && byteFrameZus.size() > 0) {

                        for (ByteFrameZu frameZus : byteFrameZus) {
                            IpTree ipTree = new IpTree();
                            ipTree.setId(frameZus.getId());
                            ipTree.setPid(tree_id);
                            ipTree.setIpTreeId(tree_id);
                            ipTree.setSectionName(frameZus.getName());
                            ipTree.setType("子帧");
                            ipTree.setIpTreeName(sectionName);
                            QueryWrapper<TreeByteList2>  treeByteList2QueryWrapper = new QueryWrapper<>();
                            treeByteList2QueryWrapper.eq("pid",frameZus.getId());
                            treeByteList2QueryWrapper.orderByAsc("index_sx");
                            List<TreeByteList2> treeByteList2s = treeByteListMapper2.selectList(treeByteList2QueryWrapper);
                            List<IpTree> byteList2 = new LinkedList<>();
                            for (TreeByteList2 treeByteList2 : treeByteList2s) {
                               //这是字节树
                               IpTree bitipTree = new IpTree();
                               bitipTree.setId(treeByteList2.getId());
                               bitipTree.setPid(frameZus.getId());
                               bitipTree.setSectionName(treeByteList2.getByteName());
                               bitipTree.setType("子帧字节");
                               bitipTree.setIpTreeId(tree_id);
                                bitipTree.setSectionName(sectionName);

                        //查找子帧位
                        QueryWrapper<BitList>  bitListQueryWrapper2 = new QueryWrapper<>();
                        bitListQueryWrapper2.eq("byte_id",treeByteList2.getId());
                        bitListQueryWrapper2.orderByAsc("index_sx");
                        List<BitList> bitLists2 = bitListMapper.selectList(bitListQueryWrapper2);
                        //这是位树
                        List<IpTree> bitChildren2= new LinkedList<>();
                        for (BitList bitList : bitLists2) {
                            IpTree bitipTree2 = new IpTree();
                            bitipTree2.setId(bitList.getId());
                            bitipTree2.setPid(treeByteList.getId());
                            bitipTree2.setSectionName(bitList.getBitName());
                            bitipTree2.setType("位");
                            bitipTree2.setIpTreeId(tree_id);
                            bitipTree2.setIpTreeName(sectionName);
                            bitChildren2.add(bitipTree2);
                        }
                        bitipTree.setChildren(bitChildren2);
                                byteList2.add(bitipTree);
                    }


                            ipTree.setChildren(byteList2);
                            byteList.add(ipTree);
                        }


                    }
                    else {

                        IpTree ipTree = new IpTree();
                        ipTree.setId(treeByteList.getId());
                        ipTree.setPid(tree_id);
                        ipTree.setIpTreeId(tree_id);
                        ipTree.setIpTreeName(sectionName);
                        ipTree.setSectionName(treeByteList.getByteName());
                        ipTree.setType("字节");

                        //往树里面添加位
                        QueryWrapper<BitList> bitListQueryWrapper = new QueryWrapper<>();
                        bitListQueryWrapper.eq("byte_id", treeByteList.getId());
                        bitListQueryWrapper.orderByAsc("index_sx");
                        List<BitList> bitLists = bitListMapper.selectList(bitListQueryWrapper);
                        List<IpTree> bitChildren = new LinkedList<>();
                        for (BitList bitList : bitLists) {
                            IpTree bitipTree = new IpTree();
                            bitipTree.setId(bitList.getId());
                            bitipTree.setPid(treeByteList.getId());
                            bitipTree.setSectionName(bitList.getBitName());
                            bitipTree.setType("位");
                            bitipTree.setIpTreeId(tree_id);
                            bitipTree.setIpTreeName(sectionName);
                            bitChildren.add(bitipTree);
                        }


                        ipTree.setChildren(bitChildren);
                        byteList.add(ipTree);
                    }
                }
                menu.setChildren(byteList);
                return menu;
            }

            menu.setChildren(getChilds(menu,ipTrees));
            return menu;
        }).collect(Collectors.toList());


        return collect;
    }

    @Override
    public List<IpTree> queryIpTreeByteByWordId(String wordId) {
        QueryWrapper<IpTree> ipTreeQueryWrapper = new QueryWrapper<>();
        ipTreeQueryWrapper.eq("word_id", wordId);
        List<IpTree> ipTrees = baseMapper.selectList(ipTreeQueryWrapper);


        //组装成父子的树形结构
        //找到所有的一级分类
        List<IpTree> collect = ipTrees.stream().filter(IpTree ->
                IpTree.getPid().equals("0")
        ).map((menu)->{
            if (menu.getType().equals("协议")){
                TreeByteList treeByteList = new TreeByteList();
                treeByteList.setIpTreeId(menu.getId());
                List<TreeByteList> treeByteLists = treeByteListService.listByTreeId(treeByteList);
                menu.setByteList(treeByteLists);
                return menu;
            }

            menu.setChildren(getChilds(menu,ipTrees));
            return menu;
        }).collect(Collectors.toList());


        return collect;

    }

    //递归查找所有菜单的子菜单
    public List<IpTree> getChilds(IpTree root,List<IpTree> all){
        List<IpTree> children = all.stream().filter(IpTree -> {
            return IpTree.getPid().equals(root.getId());
        }).map(IpTree -> {
            if (IpTree.getType().equals("协议")){
                String tree_id = IpTree.getId();
                QueryWrapper<TreeByteList>  treeByteListQueryWrapper = new QueryWrapper<>();
                //往树里面添加字节
                treeByteListQueryWrapper.eq("ip_tree_id",tree_id);
                treeByteListQueryWrapper.orderByAsc("index_sx");

                List<TreeByteList> treeByteLists = treeByteListMapper.selectList(treeByteListQueryWrapper);
                List<IpTree> byteList = new LinkedList<>();
                for (TreeByteList treeByteList : treeByteLists) {
                    IpTree ipTree = new IpTree();
                    ipTree.setId(treeByteList.getId());
                    ipTree.setPid(tree_id);
                    ipTree.setIpTreeId(tree_id);
                    ipTree.setSectionName(treeByteList.getByteName());
                    ipTree.setType("字节");
                    //往树里面添加位
                    QueryWrapper<BitList>  bitListQueryWrapper = new QueryWrapper<>();
                    bitListQueryWrapper.eq("byte_id",treeByteList.getId());
                    bitListQueryWrapper.orderByAsc("index_sx");
                    List<BitList> bitLists = bitListMapper.selectList(bitListQueryWrapper);
                    List<IpTree> bitChildren= new LinkedList<>();
                    for (BitList bitList : bitLists) {
                        IpTree bitipTree = new IpTree();
                        bitipTree.setId(bitList.getId());
                        bitipTree.setPid(treeByteList.getId());
                        bitipTree.setSectionName(bitList.getBitName());
                        bitipTree.setType("位");
                        bitipTree.setIpTreeId(tree_id);
                        bitChildren.add(bitipTree);
                    }
                    ipTree.setChildren(bitChildren);
                    byteList.add(ipTree);
                }
                IpTree.setChildren(byteList);
                return IpTree;
            }

            //找到子菜单
            IpTree.setChildren(getChilds(IpTree,all));
            return IpTree;
        }).collect(Collectors.toList());
        return children;
    }





    /**
	 * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
	 * @param pid
	 */
	private void updateOldParentNode(String pid) {
		if(!IIpTreeService.ROOT_PID_VALUE.equals(pid)) {
			Long count = baseMapper.selectCount(new QueryWrapper<IpTree>().eq("pid", pid));
			if(count==null || count<=1) {
				baseMapper.updateTreeNodeStatus(pid, IIpTreeService.NOCHILD);
			}
		}
	}

	/**
     * 递归查询节点的根节点
     * @param pidVal
     * @return
     */
    private IpTree getTreeRoot(String pidVal){
        IpTree data =  baseMapper.selectById(pidVal);
        if(data != null && !IIpTreeService.ROOT_PID_VALUE.equals(data.getPid())){
            return this.getTreeRoot(data.getPid());
        }else{
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<IpTree> dataList = baseMapper.selectList(new QueryWrapper<IpTree>().eq("pid", pidVal));
        if(dataList != null && dataList.size()>0){
            for(IpTree tree : dataList) {
                if(!sb.toString().contains(tree.getId())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(),sb);
            }
        }
        return sb;
    }



}
